<?php

namespace common\service;

use common\model\EntityModel;
use common\model\PlanModel;
use common\model\ProjectMemberModel;
use common\model\StatusModel;
use common\model\StepCategoryModel;
use common\model\UserModel;
use support\SingletonTrait;
use common\model\ReviewRequestModel;
use common\model\TaskModel;
use common\model\TaskWorkOrderModel;
use common\model\WorkTimeRecordModel;

class ProjectTaskProgressService
{

    // 单例工具
    use SingletonTrait;

    /**
     * @var object|\think\Model|\think\model\RelationModel
     */
    public $planModel;

    /**
     * @var object|\think\Model|\think\model\RelationModel
     */
    public $entityModel;

    public function __construct()
    {
        $this->planModel = model(PlanModel::class);
        $this->entityModel = model(EntityModel::class);
    }

    /**
     * 查询需求变更情况列表
     * @param $filter
     * @param $page
     * @return array
     */
    public function getDemandChangeList($filter, $page)
    {

        // 如果按今日查
        if (!empty($filter['month'])) {
            $filter['start_time'] = strtotime(date('Y-m-d', strtotime($filter['month'])));
            $filter['end_time'] = strtotime('+1 day', strtotime(date('Y-m-d', strtotime($filter['month'])))) - 1;
        }

        $projectId = $filter['project_id'];
        $startTime = $filter['start_time'] ?? strtotime(date('Y-m-d', time()));
        $endTime = $filter['end_time'] ?? strtotime('+1 day', strtotime(date('Y-m-d', time()))) - 1;;
        $stepCategoryIdList = $filter['step_category_id_list'];

        // 获得排期完成的剧集和环节信息
        $planEpisodeStepCategoryList = $this->getPlanEpisodeStepCategoryList($projectId, $stepCategoryIdList, $startTime, $endTime);
        if (empty($planEpisodeStepCategoryList)) {
            return [
                'rows' => [],
                'total_list' => []
            ];
        }
        $statusClosedClose = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $episodeIdList = array_column($planEpisodeStepCategoryList, 'episode_id');
        $stepCategoryIdList = array_column($planEpisodeStepCategoryList, 'step_category_id');
        // 获取实体列表
        $entityFilter['task.episode_id'] = ['IN', $episodeIdList];
        $entityFilter['task.step_category_id'] = ['IN', $stepCategoryIdList];
        if (!empty($filter['grade'])) {
            $entityFilter["JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.',m.code,'_grade')))"] = ['IN', $filter['grade']];
        }
        if (!empty($filter['category'])) {
            $entityFilter["JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.',m.code,'_category')))"] = ['IN', $filter['category']];
        }
        if (!empty($filter['search_name'])) {
            $entityFilter[] = [
                ['entity.name' => ['LIKE', '%' . $filter['search_name'] . '%']],
                ['entity.code' => ['LIKE', '%' . $filter['search_name'] . '%']],
                ['task.name' => ['LIKE', '%' . $filter['search_name'] . '%']],
                '_logic' => 'OR'
            ];
        }
        if (!empty($filter['is_append']) && $filter['is_append'] == 'yes') {
            $entityFilter['is_append'] = $filter['is_append'];
            $entityFilter["JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))"] = ['NEQ', $statusClosedClose['id']];
        }
        if (!empty($filter['is_closed']) && $filter['is_closed'] == 'yes') {
            $entityFilter["JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))"] = $statusClosedClose['id'];
        }
        $entityFilter[] = [
            ['entity.is_append' => 'yes'],
            ["JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => $statusClosedClose['id']],
            '_logic' => 'OR'
        ];
        $entityList = $this->getEntityList($entityFilter, $page, $filter['is_append'] ?? null, $filter['is_closed'] ?? null);

        $totalList = $entityList['total_list'] ?? [];
        // 查询镜头动画时长
        $shotStepCategoryParentIds = model(StepCategoryModel::class)->where(['id' => ['IN', $filter['step_category_id_list']]])->column('parent_id');
        $shotStepCategoryCodes = model(StepCategoryModel::class)->where(['id' => ['IN', $shotStepCategoryParentIds]])->column('code');
        $shotMotion = ['append' => 0, 'closed' => 0];
        if (in_array('shot', $shotStepCategoryCodes)) {
            $shotMotion = $this->getShotMotionTaskList($episodeIdList, $projectId);
        }
        if (!empty($shotMotion)) {
            $totalList['duration_list'] = $shotMotion;
        }
        return [
            'rows' => $entityList['list'] ?? [],
            'total_list' => $totalList
        ];
    }

    /**
     * 获得排期完成的剧集和环节信息
     * @param $project
     * @param $stepCategoryIdList
     * @param $startTime
     * @param $endTime
     * @return array|mixed|string
     */
    public function getPlanEpisodeStepCategoryList($project, $stepCategoryIdList, $startTime, $endTime)
    {
        $filter = [];
        if (!empty($project)) {
            $filter['plan.project_id'] = $project;
        }
        if (!empty($startTime) && !empty($endTime)) {
            $filter['plan.end_time'] = ['BETWEEN', [$startTime, $endTime]];
        }
        if (!empty($stepCategoryIdList)) {
            $filter['r_step_category.link_id'] = ['IN', $stepCategoryIdList];
        }
        $planEpisodeStepCategoryList = $this->planModel
            ->join("task_relation_tag r_step_category on link_module_code in ('step_category','show_step_category') and r_step_category.task_id = plan.task_id")
            ->where(['plan.scope' => 'single', 'plan.type' => 'step_category'])
            ->where($filter)
            ->field('plan.entity_id as episode_id,r_step_category.link_id as step_category_id,max(plan.end_time) max_end_time')
            ->group('plan.entity_id,r_step_category.link_id')
            ->select();
        if (empty($planEpisodeStepCategoryList)) {
            return [];
        }
        return $planEpisodeStepCategoryList;
    }


    /**
     * 实体列表
     * @param $filter
     * @param $page
     * @param $isAppend
     * @param $isClosed
     * @return array
     */
    public function getEntityList($filter, $page, $isAppend, $isClosed)
    {
        $entityFields = [
            'task.id as task_id', 'task.name as task_name', "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status')) as task_status",
            'entity.id as entity_id', 'entity.name as entity_name', 'entity.project_id',
            'entity.initial_episode_code', 'entity.showings_number', 'entity.is_append', 'entity.json as entity_json',
            "JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.',m.code,'_grade'))) as grade",
            "JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.',m.code,'_category'))) as category",
            'step.id as step_id', 'step.name as step_name',
            'step_category.id as step_category_id', 'step_category.name as step_category_name',
            'm.id as module_id', 'm.code as module_code'
        ];

        $statusClosedClose = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $totalList = [
            'append_num' => 0,
            'closed_num' => 0
        ];
        // 新加需求
        if ($isClosed != 'yes') {
            $appendList = $this->entityModel
                ->join('task on task.entity_id = entity.id')
                ->join('step_category on step_category.id = task.step_category_id', 'LEFT')
                ->join('step on step.id = task.step_id', 'LEFT')
                ->join('module m on entity.module_id = m.id')
                ->where($filter)
                ->where(['entity.is_append' => 'yes'])
                ->where(["JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => ['NEQ', $statusClosedClose['id']]])
                ->group('task.step_category_id,entity.id')
                ->field('entity.id')->select();
            if (!empty($appendList)) {
                $appendIds = array_column($appendList, 'id');
                $appendNum = $this->entityModel->where(['id' => ['IN', $appendIds]])->count();
                $totalList['append_num'] = $appendNum;
            }
        }

        // 废除
        if ($isAppend != 'yes') {
            $closedEntityList = $this->entityModel
                ->join('task on task.entity_id = entity.id')
                ->join('step_category on step_category.id = task.step_category_id', 'LEFT')
                ->join('step on step.id = task.step_id', 'LEFT')
                ->join('module m on entity.module_id = m.id')
                ->where($filter)
                ->where(["JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => ['EQ', $statusClosedClose['id']]])
                ->group('task.step_category_id,entity.id')
                ->field('entity.id')->select();
            if (!empty($closedEntityList)) {
                $closedEntityIds = array_column($closedEntityList, 'id');
                $closedNum = $this->entityModel->where(['id' => ['IN', $closedEntityIds]])->count();
            }
            if (!empty($closedNum)) {
                $totalList['closed_num'] = $closedNum;
            }
        }

        $statusList = model(StatusModel::class)->select();
        $statusMap = array_column($statusList, null, 'id');
        $entityList = $this->entityModel
            ->join('task on task.entity_id = entity.id')
            ->join('step_category on step_category.id = task.step_category_id', 'LEFT')
            ->join('step on step.step_category_id = step_category.id', 'LEFT')
            ->join('module m on entity.module_id = m.id')
            ->field($entityFields)
            ->where($filter)
            ->page(...$page)
            ->group('task.step_category_id,entity.id')
            ->select();
        // 总数
        $totalList['total'] = $totalList['append_num'] + $totalList['closed_num'];
        $entityList = array_map(function ($tmp) use ($statusMap) {

            $entityJson = json_decode($tmp['entity_json'], true);
            unset($tmp['entity_json']);
            if (!in_array($tmp['module_code'], ['shot', 'level', 'asset'])) {
                $upstreamEntityId = $tmp['entity_id'];
            } else {
                $isShot = $tmp['module_code'] == 'shot';
                $upstreamEntityField = $tmp['module_code'] . ($isShot ? '_storyboard' : '_design');
                $upstreamEntityId = $entityJson[$upstreamEntityField] ?? 0;
            }
            $tmp['upstream_entity_id'] = $upstreamEntityId;
            $tmp['task_status'] = $statusMap[$tmp['task_status']] ?? [];
            return $tmp;
        }, $entityList);

        return ['list' => $entityList ?? [], 'total_list' => $totalList];
    }

    /**
     * 查询镜头动画时长
     * @param $taskEpisodeId
     * @param $projectId
     * @return array|int|int[]
     */
    public function getShotMotionTaskList($taskEpisodeId, $projectId)
    {
        // 动画查询时长
        $stepCategoryIds = model(StepCategoryModel::class)->where(['code' => 'shot_motion'])->column('id');
        $where = [
            'task.episode_id' => ['IN', $taskEpisodeId],
            'step_category_id' => ['IN', $stepCategoryIds],
            'entity.module_id' => ['IN', [module_by_code('shot')['id'], module_by_code('storyboard')['id']]],
            'entity.project_id' => $projectId
        ];
        $shotMotionList = $this->entityModel
            ->join('task on task.entity_id = entity.id')
            ->field("entity.duration as duration,entity.is_append,JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status')) as task_status")
            ->where($where)
            ->where("duration !=''")
            ->group('task.step_category_id,entity.id')
            ->select();
        if (empty($shotMotionList)) {
            return 0;
        }
        $appendDuration = 0;
        $closedDuration = 0;
        $statusClosedDefaultId = StatusService::getInstance()->getTaskDefaultClosedStatus();

        foreach ($shotMotionList as $item) {
            if (preg_match('|(\d+)|', $item['duration'], $r)) {
                if ($item['is_append'] == 'yes' && $item['task_status'] != $statusClosedDefaultId['id']) {
                    $appendDuration += $r[1];
                }
                if ($item['task_status'] == $statusClosedDefaultId['id']) {
                    $closedDuration += $r[1];
                }
            }
        }
        return ['append' => $appendDuration, 'closed' => $closedDuration];
    }

    /**
     * 获取环节任务进度列表
     * @throws \Exception
     */
    public function getStepCategoryTaskProgressList($param, $tenantId)
    {
        $projectId = $param['filter']['project_id'];
        $stepCategoryIds = $param['filter']['step_category_ids'];
        $type = $param['type'] ?? "abnormal";
        $showUndone = isset($param['filter']['show_undone']) && $param['filter']['show_undone'] == "yes";
        $untreatedAbnormal = isset($param['filter']['untreated_abnormal']) && $param['filter']['untreated_abnormal'] == "yes";
        $startTime = $param['filter']['start_time'];
        $endTime = $param['filter']['end_time'];
        $page = $param['page'] ?? [1, C("default_page_total")];

        $res = [
            'total' => 0,
            "rows" => []
        ];

        //查询异常人员
        $taskFilter = [];
        $abnormalFilter = [];
        $overdueUndoneFilter = [];
        $taskPlanFilter = [];
        $episodeStepCategoryFilter = [];
        $currentTime = time();
        $finalStatusId = 0;

        $closedStatus = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $finalStatus = StatusService::getInstance()->getTaskDoneStatus();
        $isDirector = $stepCategoryIds[0] == 0;
        if ($isDirector) {
            $countFilter = [
                "task.project_id" => $projectId,
                "task.step_type" => ['NOT IN', ['step_category', 'step']],
                "task.json->>'$.task_status'" => ['NEQ', $closedStatus['id']],
            ];
        } else {
            $countFilter = [
                "task.project_id" => $projectId,
                "task.step_type" => ['NEQ', 'step_category'],
                "task.json->>'$.task_status'" => ['NEQ', $closedStatus['id']],
            ];
        }

        if (!empty($undone)) {
            $countFilter["task.json->>'$.task_status'"] = ['NEQ', $finalStatus['id']];
        }

        //查询为解决的异常
        $noDealStatus = join(",", TaskWorkOrderModel::STATUS_NOT_CLOSED_GROUP);
        if ($untreatedAbnormal || $showUndone) {
            $finalStatusId = $finalStatus['id'];

            $taskFilterData = $this->getTaskFilter($startTime, $endTime, $projectId, $stepCategoryIds, $currentTime);
            //计划完成条件
            $taskPlanFilter = $taskFilterData['task_plan_filter'];
            //计划交付条件
            $episodeStepCategoryFilter = $taskFilterData['episode_step_category_filter'];
            // 计划交付 + 计划完成条件
            $taskFilter = $taskFilterData['task_filter'];

            $undoneOverdueFilter = $taskFilterData['undone_overdue_filter'];
            $finalOverdueFilter = $taskFilterData['final_overdue_filter'];
            $abnormalFilter = $this->getAbnormalQueryFilter($currentTime, $finalOverdueFilter, $undoneOverdueFilter, $finalStatusId);

            //逾期未完成
            $taskMemberUserIds = [];
            if ($untreatedAbnormal) {
                $overdueUndoneFilter = $abnormalFilter['overdue_undone_filter'];
                //异常条件
                $abnormalFilter = $abnormalFilter['abnormal_filter'];
                $abnormalTaskMemberFilter = $countFilter;
                $abnormalTaskMemberFilter[] = [["task_work_order.id" => ["GT", 0]], [$overdueUndoneFilter], "_logic" => "OR"];
                switch ($type) {
                    case "plan_final":
                        $abnormalTaskMemberFilter[] = $taskPlanFilter;
                        break;
                    case "plan_delivery":
                        $abnormalTaskMemberFilter[] = $episodeStepCategoryFilter;
                        break;
                    case "abnormal":
                    default:
                        $abnormalTaskMemberFilter[] = $taskFilter;
                        break;
                }

                $abnormalTaskMember = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task_member.task_id = task.id")
                    ->join("task_work_order on task_work_order.task_id = task.id and task_work_order.status in ({$noDealStatus})", "LEFT")
                    ->where($abnormalTaskMemberFilter)
                    ->field([
                        "task_member.user_id",
                    ])
                    ->group("task_member.user_id")
                    ->select();

                if (empty($abnormalTaskMember)) {
                    return $res;
                }

                $abnormalTaskMember = array_column($abnormalTaskMember, 'user_id', 'user_id');
                $taskMemberUserIds = array_values($abnormalTaskMember);
            }

            //未完成处理
            if ($showUndone) {
                $undoneTaskMemberFilter = $countFilter;

                if ($type == "plan_delivery") {
                    if (empty($episodeStepCategoryFilter)) {
                        return $res;
                    }
                    $undoneTaskMemberFilter[] = [$episodeStepCategoryFilter];
                } else {
                    $undoneTaskMemberFilter[] = [$taskPlanFilter];
                }

                $undoneTaskMemberFilter["task.json->>'$.task_status'"] = ["NEQ", $finalStatusId];
                $undoneTaskMember = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task_member.task_id = task.id")
                    ->where($undoneTaskMemberFilter)
                    ->field([
                        "task_member.user_id",
                    ])
                    ->group("task_member.user_id")
                    ->select();

                if (empty($undoneTaskMember)) {
                    return $res;
                }

                $undoneTaskMember = array_column($undoneTaskMember, 'user_id', 'user_id');
                $taskMemberUserIds = array_values($undoneTaskMember);
            }

            $abnormalTaskMemberList = model(UserModel::class)->where(['id' => ["IN", $taskMemberUserIds]])->field("union_id")->select();
            $projectMemberList = array_column($abnormalTaskMemberList, 'union_id', 'union_id');
        } else {
            //查询项目人员
            $projectMemberFilter = ['project_id' => $projectId];
            if ($isDirector) {
                $projectMemberFilter['role_code'] = 'director';
            }

            $projectMemberList = model(ProjectMemberModel::class)
                ->join("user on user.id = project_member.user_id")
                ->where($projectMemberFilter)
                ->field("union_id")
                ->select();

            if (empty($projectMemberList)) {
                return $res;
            }

            $projectMemberList = array_column($projectMemberList, 'union_id', 'union_id');
        }

        $requestData = [
            "param" => [
                "department_step_category_ids" => join(",", $stepCategoryIds),
                "filter" => [
                    "tenant_id" => $tenantId,
                    "user_id" => ["-in", join(",", $projectMemberList)],
                ],
                "page" => [$page[0], $page[1]]
            ]
        ];

        if (isset($param['filter']['user_name'])) {
            $requestData["param"]["filter"]["user_name"] = $param['filter']['user_name'];
        }

        $res = TenantService::getInstance()->selectDepartmentUser($tenantId, $requestData);

        if (empty($res['rows'])) {
            return $res;
        }

        $userIds = [];
        $saasUserIds = [];
        foreach ($res['rows'] as $departmentUserItem) {
            if (empty($departmentUserItem['saas_user_id'])) {
                continue;
            }

            $res['rows_new'][] = [
                'im_user_id' => $departmentUserItem['user_id'],
                'user_id' => $departmentUserItem['saas_user_id'],
                'name' => $departmentUserItem['name'],
                'department_info' => array_column($departmentUserItem['department_info'], 'name')
            ];
            $userIds[] = $departmentUserItem['user_id'];
            $saasUserIds[] = $departmentUserItem['saas_user_id'];
        }
        $res['rows'] = $res['rows_new'];
        unset($res['rows_new']);

        if (empty($res['rows'])) {
            return $res;
        }

        //在把计划查出来
        if (!$untreatedAbnormal) {
            $finalStatus = StatusService::getInstance()->getTaskDoneStatus();
            $finalStatusId = $finalStatus['id'];

            $taskFilterData = $this->getTaskFilter($startTime, $endTime, $projectId, $stepCategoryIds, $currentTime);
            //计划完成条件
            $taskPlanFilter = $taskFilterData['task_plan_filter'];
            //计划交付条件
            $episodeStepCategoryFilter = $taskFilterData['episode_step_category_filter'];
            // 计划交付 + 计划完成条件
            $taskFilter = $taskFilterData['task_filter'];

            $undoneOverdueFilter = $taskFilterData['undone_overdue_filter'];
            $finalOverdueFilter = $taskFilterData['final_overdue_filter'];
            $abnormalFilter = $this->getAbnormalQueryFilter($currentTime, $finalOverdueFilter, $undoneOverdueFilter, $finalStatusId);
            //逾期未完成
            $overdueUndoneFilter = $abnormalFilter['overdue_undone_filter'];
            //异常条件
            $abnormalFilter = $abnormalFilter['abnormal_filter'];
        }

        // 统计工单未完成,交付数量,计划完成数量
        // 逾期 (task.end_time=0 and plan.end_time < time()) or (task.end_time>0 and task.end_time > plan.end_time)
        //异常情况 工单未处理,逾期未完成
        $countFilter["task_member.user_id"] = ["IN", $saasUserIds];

        // 交付统计
        $deliveryCountMap = [];
        $deliveryCompleteCountMap = [];
        if (!empty($episodeStepCategoryFilter)) {
            $deliveryCountFilter = $countFilter;
            $deliveryCountFilter[] = [$episodeStepCategoryFilter];
            $deliveryCountMap = $this->getMemberTaskCount($deliveryCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task.id) as delivery_count"
            ]);

            $deliveryCountFilter["task.json->>'$.task_status'"] = $finalStatusId;
            $deliveryCompleteCountMap = $this->getMemberTaskCount($deliveryCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task.id) as delivery_complete_count"
            ]);
        }

        // 计划统计
        $planCountMap = [];
        $planCompleteCountMap = [];
        if (!empty($taskPlanFilter)) {
            $planCountFilter = $countFilter;
            $planCountFilter[] = $taskPlanFilter;
            $planCountMap = $this->getMemberTaskCount($planCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task.id) as plan_count"
            ], false);

            //计划完成
            $planCountFilter["task.json->>'$.task_status'"] = $finalStatusId;
            $planCompleteCountMap = $this->getMemberTaskCount($planCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task.id) as plan_complete_count"
            ], false);
        }

        //异常工单统计
        $abnormalCountMap = [];
        $abnormalCompleteCountMap = [];
        if (!empty($taskFilter) && !empty($abnormalFilter)) {
            $abnormalCountFilter = $countFilter;
            $abnormalCountFilter[] = $taskFilter;
            $abnormalCountFilter[] = $abnormalFilter;
            $abnormalCountMap = $this->getMemberTaskCount($abnormalCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task.id) as abnormal_count",
                "COUNT(distinct task_work_order.id) as task_work_order_count"
            ], true, "all");

            //异常未完成任务统计 (工单未完成且逾期未完成)
            $abnormalUndoCountFilter = $countFilter;
            $abnormalUndoCountFilter[] = $taskFilter;
            $abnormalUndoCountFilter[] = [["task_work_order.id" => ["GT", 0]], [$overdueUndoneFilter], "_logic" => "OR"];
            $abnormalUndoCountMap = $this->getMemberTaskCount($abnormalUndoCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task.id) as abnormal_unsolved_count"
            ], true, "not_closed", $noDealStatus);

            // 获取完成统计
            foreach ($abnormalCountMap as $taskMember => $abnormalCountItem) {
                $abnormalUnsolvedCount = $abnormalUndoCountMap[$taskMember]['abnormal_unsolved_count'] ?? 0;
                $abnormalCompleteCountMap[$taskMember] = ['abnormal_solve_count' => $abnormalCountItem['abnormal_count'] - $abnormalUnsolvedCount];
            }
        }

        //工单完成数量
        $workOrderCompleteCountMap = [];
        if (!empty($taskFilter)) {
            $workOrderCompleteCountFilter = $countFilter;
            $workOrderCompleteCountFilter[] = $taskFilter;
            $workOrderCompleteCountFilter["task_work_order.status"] = TaskWorkOrderModel::STATUS_PROCESSED;
            $workOrderCompleteCountMap = $this->getMemberTaskCount($workOrderCompleteCountFilter, [
                "task_member.user_id",
                "COUNT(distinct task_work_order.id) as work_order_solve_count"
            ], true, "all");
        }

        // 工作情况
        // 查询钉钉工时
        $paramData = [
            'user_id_list' => $userIds,
            'work_date_from' => date('Y-m-d H:i:s', $startTime),
            'work_date_to' => date('Y-m-d H:i:s', $endTime)
        ];

        $workHouseList = teamones_request("teamones-work-hour", "dingtalk/get_user_work_times", $paramData)['data'] ?? [];
        $workHouseMap = array_column($workHouseList, 'work_hour', 'user_id');

        //产能饱和
        $workTimeRecordList = model(WorkTimeRecordModel::class)
            ->where([
                'user_id' => ["IN", $saasUserIds],
                ['record_time' => ["EGT", $startTime]], ['record_time' => ["ELT", $endTime]]
            ])
            ->field("user_id,count(work_time) as work_time_count")
            ->group("user_id")
            ->select();
        $workTimeRecordList = array_column($workTimeRecordList, 'work_time_count', 'user_id');

        // 填充数据
        foreach ($res['rows'] as $resIndex => $resItem) {
            //交付数量
            $resItem['delivery_count'] = $deliveryCountMap[$resItem['user_id']]['delivery_count'] ?? 0;
            $resItem['delivery_complete_count'] = $deliveryCompleteCountMap[$resItem['user_id']]['delivery_complete_count'] ?? 0;
            //计划数量
            $resItem['plan_count'] = $planCountMap[$resItem['user_id']]['plan_count'] ?? 0;
            $resItem['plan_complete_count'] = $planCompleteCountMap[$resItem['user_id']]['plan_complete_count'] ?? 0;
            // 异常任务数
            $resItem['abnormal_count'] = $abnormalCountMap[$resItem['user_id']]['abnormal_count'] ?? 0;
            $resItem['abnormal_solve_count'] = $abnormalCompleteCountMap[$resItem['user_id']]['abnormal_solve_count'] ?? 0;
            // 工单数量统计
            $resItem['work_order_count'] = $abnormalCountMap[$resItem['user_id']]['task_work_order_count'] ?? 0;
            $resItem['work_order_solve_count'] = $workOrderCompleteCountMap[$resItem['user_id']]['work_order_solve_count'] ?? 0;
            // 工时数量
            $resItem['work_hour'] = $workHouseMap[$resItem['im_user_id']] ?? 0;
            $resItem['task_hour'] = $workTimeRecordList[$resItem['user_id']] ?? 0;
            $res['rows'][$resIndex] = $resItem;
        }

        return $res;
    }

    /**
     * 获取任务进度详情列表
     * @param $param
     * @return array
     * @throws \Exception
     */
    public function getTaskProgressInfoList($param)
    {
        $projectId = $param['filter']['project_id'];
        $stepCategoryIds = $param['filter']['step_category_ids'];
        $startTime = $param['filter']['start_time'];
        $endTime = $param['filter']['end_time'];
        $userId = $param['filter']['user_id'];
        $showUndoTask = isset($param['filter']['show_undo_task']) && $param['filter']['show_undo_task'] == "yes";
        $showUnSolveAbnormal = isset($param['filter']['show_unsolved_abnormal']) && $param['filter']['show_unsolved_abnormal'] == "yes";
        $page = $param['page'] ?? [1, C('default_page_total')];

        $statusList = model(StatusModel::class)->field('id,name,code,color,icon')->cache(6 * 60)->select();
        $statusMap = [];
        $finalStatusId = 0;
        $reviewingStatusId = 0;
        $statusCodeMap = [];
        foreach ($statusList as $statusItem) {
            $statusCodeMap[$statusItem['code']] = $statusItem;

            if ($statusItem['code'] == 'final') {
                $finalStatusId = $statusItem['id'];
            }

            if ($statusItem['code'] == "submitted") {
                $reviewingStatusId = $statusItem['id'];
            }

            $statusMap[$statusItem['id']] = $statusItem;
        }

        $taskFilter = [
            "task.project_id" => $projectId,
            "task.step_type" => ["NEQ", TaskModel::STEP_TYPE_STEP_CATEGORY],
            "task_member.user_id" => $userId,
            "task.json->>'$.task_status'" => ['NEQ', $statusCodeMap['closed']['id']],
        ];

        if (isset($param['filter']['category'])) {
            $taskFilter["JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.', module.code, '_', 'category')))"] = $param['filter']['category'];
        }

        if (isset($param['filter']['grade'])) {
            $taskFilter["JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.', module.code, '_', 'grade')))"] = $param['filter']['grade'];
        }

        //查询实体或者代表的任务名字
        if (isset($param['filter']['name'])) {
            $taskFilter[] = [
                "entity.name" => $param['filter']['name'],
                "task.name" => $param['filter']['name'],
                "_logic" => "OR"
            ];
        }


        $planMap = [];
        $finalOverdueFilter = [];
        $undoneOverdueFilter = [];
        $unSolveFilter = [];
        $currentTime = time();
        switch ($param['type']) {
            case 'plan_final':
                $taskFilter[] = [['task.plan_end_time' => ['EGT', $startTime]], ['task.plan_end_time' => ['ELT', $endTime]], 'r_step_category.link_id' => ["IN", $stepCategoryIds]];

                //展示未完成
                if ($showUndoTask) {
                    $taskFilter["task.json->>'$.task_status'"] = ['NEQ', $finalStatusId];
                }
                break;
            case 'plan_delivery':
                //在把计划查出来
                $filterData = $this->getTaskFilter($startTime, $endTime, $projectId, $stepCategoryIds, $currentTime);
                $episodeStepCategoryFilter = $filterData['episode_step_category_filter'];
                $finalOverdueFilter = $filterData['final_overdue_filter'];
                $undoneOverdueFilter = $filterData['undone_overdue_filter'];
                $planMap = $filterData['plan_map'];

                if (!empty($episodeStepCategoryFilter)) {
                    $taskFilter[] = $episodeStepCategoryFilter;
                }

                //展示未完成
                if ($showUndoTask) {
                    $taskFilter["task.json->>'$.task_status'"] = ['NEQ', $finalStatusId];
                }
                break;
            case 'abnormal':
                // 异常情况 (有工单 ,且逾期) [时间范围 = 计划集 + 任务时间范围的]
                $filterData = $this->getTaskFilter($startTime, $endTime, $projectId, $stepCategoryIds, $currentTime);
                $undoneOverdueFilter = $filterData['undone_overdue_filter'];
                $finalOverdueFilter = $filterData['final_overdue_filter'];
                $planMap = $filterData['plan_map'];
                $abnormalFilterData = $this->getAbnormalQueryFilter($currentTime, $finalOverdueFilter, $undoneOverdueFilter, $finalStatusId);
                $abnormalFilter = $abnormalFilterData['abnormal_filter'];
                $overdueUndoneFilter = $abnormalFilterData['overdue_undone_filter'];
                //未解决筛选
                $unSolveFilter = [
                    $taskFilter,
                    $filterData['task_filter'],
                    [["task_work_order.id" => ["GT", 0]], $overdueUndoneFilter, "_logic" => "OR"],
                ];

                if ($showUnSolveAbnormal) { //查询未解决的异常
                    $taskFilter = $unSolveFilter;
                } else { //不查询未解决异常
                    $taskFilter[] = [$filterData['task_filter'], $abnormalFilter];
                }

                break;
        }

        $res = [
            'rows' => [],
            'total' => 0,
        ];

        $noCloseStatus = join(",", TaskWorkOrderModel::STATUS_NOT_CLOSED_GROUP);
        $taskProgressInfoCount = $this->dealTaskProgressInfoCount($taskFilter, $param['type'], $statusCodeMap, $noCloseStatus, $finalOverdueFilter, $undoneOverdueFilter, $unSolveFilter);
        $res = array_merge($res, $taskProgressInfoCount);

        if ($res['total'] == 0) {
            return $res;
        }
        $taskFields = [
            "task.id as task_id", "task.name as task_name", "task.plan_end_time", "task.end_time", "task.step_category_id", "task.episode_id",
            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status')) as task_status", "task.step_type",
            "entity.initial_episode_code", "entity.showings_number", "entity.name", "entity.director_star",
            "JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.',module.code,'_category'))) as category",
            "JSON_UNQUOTE(JSON_EXTRACT(entity.json,CONCAT('$.',module.code,'_grade'))) as grade",
            "count(task_work_order.task_id>0 and task_work_order.status in ({$noCloseStatus}) or null) as unresolved_work_order_count"
        ];

        $taskQuery = model(TaskModel::class)
            ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
            ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
            ->join("task_member on task.id = task_member.task_id")
            ->join("entity on task.entity_id = entity.id", 'LEFT')
            ->join("module on entity.module_id = module.id", 'LEFT');

        if ($showUnSolveAbnormal) {
            $taskQuery = $taskQuery->join("task_work_order on task_work_order.task_id = task.id and task_work_order.status in ({$noCloseStatus})", "LEFT");
        } else {
            $taskQuery = $taskQuery->join("task_work_order on task_work_order.task_id = task.id", "LEFT");
        }

        $taskList = $taskQuery->where($taskFilter)
            ->field($taskFields)
            ->page(...$page)
            ->group("task.id")
            ->select();

        if (empty($taskList)) {
            return $res;
        }

        $reviewingTaskIds = [];
        $stepCategoryIds = [];
        foreach ($taskList as $taskItem) {
            if ($reviewingStatusId == $taskItem['task_status']) {
                $reviewingTaskIds[] = $taskItem['task_id'];
            }
            $stepCategoryIds[] = $taskItem['step_category_id'];
        }


        $stepCategoryList = [];
        if (!empty($stepCategoryIds)) {
            $stepCategoryIds = array_unique($stepCategoryIds);
            $stepCategoryList = model(StepCategoryModel::class)->where(['id' => ["IN", $stepCategoryIds]])->field("id,name")->select();
            $stepCategoryList = array_column($stepCategoryList, 'name', 'id');
        }

        // 查询审核进度
        $reviewProgressData = [];
        $versionReviewRequestMap = [];
        $taskVersionMap = [];
        if (!empty($reviewingTaskIds)) {
            $maxVersion = VersionService::getInstance()->getTaskMaxVersionInfo($reviewingTaskIds, "id,number,link_id,param,is_publish,is_pass,description");
            if (!empty($maxVersion)) {
                $maxVersionIds = [];
                foreach ($maxVersion as $maxVersionItem) {
                    $maxVersionIds[] = $maxVersionItem['id'];
                    $taskVersionMap[$maxVersionItem['link_id']] = $maxVersionItem['id'];
                }
                $reviewRequestList = model(ReviewRequestModel::class)
                    ->where(['module_id' => module_by_code('version')['id'], 'link_id' => ['IN', $maxVersionIds]])
                    ->select();

                $reviewRequestIdList = array_column($reviewRequestList, 'id');
                // 获取审核进度
                $versionReviewRequestMap = array_column($reviewRequestList, 'id', 'link_id');
                $reviewProgressData = ReviewRequestService::getInstance()->queryReviewRequestProgressData($reviewRequestIdList);
            }
        }

        // 组合数据
        foreach ($taskList as $taskIndex => $taskItem) {
            $overdue = 0;
            $planEndTime = 0;
            switch ($param['type']) {
                case 'plan_final':
                    $planEndTime = $taskItem['plan_end_time'];
                    break;
                case 'plan_delivery':
                    $planEndTime = $planMap[$taskItem['episode_id'] . "_" . $taskItem['step_category_id']]['plan_end_time'] ?? 0;
                    break;
            }

            if (!empty($planEndTime)) {
                if ($taskItem['end_time'] > 0) {
                    if ($taskItem['end_time'] > $planEndTime) {
                        $overdue = $taskItem['end_time'] - $taskItem['plan_end_time'];
                    }
                } else {
                    if ($planEndTime < time()) {
                        $overdue = time() - $planEndTime;
                    }
                }
            }

            $taskItem['abnormal_detail'] = [
                'is_complete' => $taskItem['task_status'] == $finalStatusId,
                'overdue' => $overdue,
                'work_order_not_handled' => $taskItem['unresolved_work_order_count'] > 0
            ];
            // 审核进度
            $linkId = $taskVersionMap[$taskItem['task_id']] ?? '';
            $reviewRequestId = $versionReviewRequestMap[$linkId] ?? 0;
            $taskItem['step_category_name'] = $stepCategoryList[$taskItem['step_category_id']] ?? "";
            if ($reviewRequestId > 0) {
                $taskItem['review_progress'] = $reviewProgressData[$reviewRequestId] ?? null;
            }

            if (isset($taskItem['task_status']) && isset($statusMap[$taskItem['task_status']])) {
                $taskItem['status'] = $statusMap[$taskItem['task_status']] ?? [];
            }

            $taskList[$taskIndex] = $taskItem;
        }
        $res['rows'] = $taskList;

        return $res;
    }

    /**
     * 获取标准会议列表
     * @param $param
     * @return array
     */
    public function getStandardMeetingList($param)
    {
        $projectId = $param['filter']['project_id'];
        $stepCategoryIds = $param['filter']['step_category_ids'];
        $startTime = $param['filter']['start_time'];
        $endTime = $param['filter']['end_time'];
        $page = $param['page'] ?? [1, C('default_page_total')];
        $showUndoTask = isset($param['filter']['show_undo_task']) && $param['filter']['show_undo_task'] == "yes";
        $closedStatus = StatusService::getInstance()->getTaskDefaultClosedStatus();
        $finalStatus = StatusService::getInstance()->getTaskDoneStatus();
        $taskFields = ['task.id', 'task.name', 'task.plan_end_time', 'task.end_time', 'task.executor', "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status')) as task_status"];

        $res = [
            'total' => 0,
            'rows' => [],
        ];

        $isDirector = $stepCategoryIds[0] == 0;

        $taskFilter = [
            'plan.type' => PlanModel::TYPE_MEETING,
            'task.project_id' => $projectId,
            'task.plan_end_time' => ['BETWEEN', [$startTime, $endTime]],
        ];

        if (isset($param['filter']['name'])) {
            $taskFilter['task.name'] = $param['filter']['name'];
        }

        //判定是否是角色还是概念查询
        if ($isDirector) {
            $roleList = model(ProjectMemberModel::class)->where(["project_id" => $projectId, 'role_code' => 'director'])->field("user_id")->select();
            $roleIds = array_column($roleList, 'user_id', 'user_id');

            if (empty($roleIds)) {
                return $res;
            }
            $taskFilter["task_member.user_id"] = ["IN", array_values($roleIds)];
        } else {
            $taskFilter["r_step_category.link_id"] = ["IN", $stepCategoryIds];
        }
        $taskFilter["task.json->>'$.task_status'"] = ['NEQ', $closedStatus['id']];

        //展示未完成的任务
        if ($showUndoTask) {
            $taskFilter["task.json->>'$.task_status'"] = ['NEQ', $finalStatus['id']];
        }

        $totalQuery = model(TaskModel::class)
            ->join("plan on plan.task_id = task.id");

        if ($isDirector) {
            $totalQuery = $totalQuery->join("task_member on task_member.task_id = plan.task_id");
        } else {
            $totalQuery = $totalQuery->join("task_relation_tag as r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')");
        }

        $res['total'] = $totalQuery
            ->where($taskFilter)
            ->count('distinct task.id');

        if ($res['total'] == 0) {
            return $res;
        }

        $taskQuery = model(TaskModel::class)
            ->join("plan on plan.task_id = task.id");

        if ($isDirector) {
            $taskQuery = $taskQuery->join("task_member on task_member.task_id = plan.task_id");
        } else {
            $taskQuery = $taskQuery->join("task_relation_tag as r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')");
        }

        $taskList = $taskQuery
            ->where($taskFilter)
            ->page(...$page)
            ->field($taskFields)
            ->group("task.id")
            ->select();

        if (empty($taskList)) {
            return $res;
        }

        $taskIds = [];
        foreach ($taskList as $taskItem) {
            $taskIds[] = $taskItem['id'];
        }

        $statusList = StatusService::getInstance()->getList([], 'id,name,code,color');
        $statusMap = [];
        $finalStatusId = 0;
        foreach ($statusList as $statusItem) {
            $statusMap[$statusItem['id']] = $statusItem;
            if ($statusItem['code'] == 'final') {
                $finalStatusId = $statusItem['id'];
            }
        }

        $taskMemberList = TaskMemberService::getInstance()->getTaskMemberUserInfoList($taskIds);
        foreach ($taskList as $taskIndex => $taskItem) {
            $taskItem['task_member_list'] = $taskMemberList[$taskItem['id']] ?? [];
            $taskItem['status'] = $statusMap[$taskItem['task_status']] ?? null;
            $taskList[$taskIndex] = $taskItem;

            $overdue = 0;
            if ($taskItem['end_time'] > $taskItem['plan_end_time']) {
                $overdue = $taskItem['end_time'] - $taskItem['plan_end_time'];
            }
            $taskItem['abnormal_detail'] = ['is_complete' => $taskItem['task_status'] == $finalStatusId, 'overdue' => $overdue];
            $taskList[$taskIndex] = $taskItem;
        }
        $res['rows'] = $taskList;

        return $res;
    }

    /**
     * 获取任务的筛选条件
     * @param $startTime
     * @param $endTime
     * @param $projectId
     * @param $stepCategoryIds
     * @param $currentTime
     * @return array
     */
    public function getTaskFilter($startTime, $endTime, $projectId, $stepCategoryIds, $currentTime)
    {
        //判定是否石导演
        $isDirector = $stepCategoryIds[0] == 0;

        $taskFilter = [];
        $taskPlanFilter = [];
        $episodeStepCategoryFilter = [];
        $undoneOverdueFilter = [];
        $finalOverdueFilter = [];
        $planMap = [];


        //是否是导演
        if ($isDirector) {
            $directorList = model(ProjectMemberModel::class)->where(['project_id' => $projectId, 'role_code' => 'director'])->field("distinct user_id")->column("user_id");
            if (!empty($directorList)) {
                $taskPlanFilter = [['task.plan_end_time' => ['EGT', $startTime]], ['task.plan_end_time' => ['ELT', $endTime]], 'task_member.user_id' => ["IN", $directorList]];
                $taskFilter = [$taskPlanFilter];
            }
        } else {
            $taskPlanFilter = [['task.plan_end_time' => ['EGT', $startTime]], ['task.plan_end_time' => ['ELT', $endTime]], 'r_step_category.link_id' => ["IN", $stepCategoryIds]];
            $taskFilter = [$taskPlanFilter];
            $planData = model(PlanModel::class)
                ->join('task_relation_tag r_step_category on plan.task_id = r_step_category.task_id')
                ->where([
                    'plan.project_id' => $projectId,
                    'plan.type' => PlanModel::TYPE_STEP_CATEGORY,
                    'plan.scope' => PlanModel::SCOPE_SINGLE,
                    ['plan.end_time' => ['EGT', $startTime]], ['plan.end_time' => ['ELT', $endTime]],
                    'r_step_category.link_module_code' => ['IN', ['step_category', 'show_step_category']],
                    'r_step_category.link_id' => ['IN', join(',', $stepCategoryIds)]
                ])
                ->field('plan.entity_id episode_id,r_step_category.link_id as step_category_id,plan.end_time,plan.start_time')
                ->group('plan.entity_id,r_step_category.link_id')
                ->cache(APP_DEBUG ? false : C('database.default_query_cache_time'))
                ->select();

            $episodeStepCategoryFilter = [];
            $undoneOverdueFilter = [];
            $finalOverdueFilter = [];
            $planMap = [];
            foreach ($planData as $planDataItem) {
                $currentFilter = ["r_episode.link_id" => $planDataItem['episode_id'], 'r_step_category.link_id' => $planDataItem['step_category_id']];
                $episodeStepCategoryFilter[] = $currentFilter;
                if (!empty($planDataItem['end_time'])) {
                    // 计划时间小于当前时间
                    if ($planDataItem['end_time'] < $currentTime) {
                        $undoneOverdueFilter[] = $currentFilter;
                    }
                    $currentFilter["task.end_time"] = ["GT", $planDataItem['end_time']];
                    $finalOverdueFilter[] = $currentFilter;
                }
                $planMap[$planDataItem['episode_id'] . "_" . $planDataItem['step_category_id']] = $planDataItem;
            }

            if (!empty($episodeStepCategoryFilter)) {
                $episodeStepCategoryFilter["_logic"] = "OR";
                $taskFilter[] = [$episodeStepCategoryFilter];
                $taskFilter["_logic"] = "OR";
            }
        }


        return [
            'task_filter' => $taskFilter,
            'task_plan_filter' => $taskPlanFilter,
            'episode_step_category_filter' => $episodeStepCategoryFilter,
            'undone_overdue_filter' => $undoneOverdueFilter,
            'final_overdue_filter' => $finalOverdueFilter,
            'plan_map' => $planMap
        ];
    }


    /**
     * 获取异常查询的条件
     * @param $currentTime
     * @param $finalOverdueFilter
     * @param $undoneOverdueFilter
     * @param $finalStatusId
     * @return array[]
     */
    public function getAbnormalQueryFilter($currentTime, $finalOverdueFilter, $undoneOverdueFilter, $finalStatusId)
    {
        //逾期完成
        $finalFilter = [["task.plan_end_time" => ["GT", 0], "_string" => "task.end_time > task.plan_end_time"]];

//        if (!empty($finalOverdueFilter)) {
//            $finalOverdueFilter["_logic"] = "OR";
//            $finalFilter[] = [$finalOverdueFilter];
//            $finalFilter["_logic"] = "OR";
//        }

        //逾期未完成
        $undoneFilter = [["task.plan_end_time" => ["GT", 0]], ["task.plan_end_time" => ["LT", $currentTime]]];
//        if (!empty($undoneOverdueFilter)) {
//            $undoneOverdueFilter["_logic"] = "OR";
//            $undoneFilter[] = $undoneOverdueFilter;
//            $undoneFilter["_logic"] = "OR";
//        }

        /**
         * 一.任务完成 (task.task_status = final and task.end_time >0)
         *  1.任务时间大于计划的结束时间
         *  plan.end_time >0 and task.episode_id =数字 and task.step_category_id in (环节) and task.end_time>plan.end_time
         *  2.任务时间大于任务的计划结束时间
         *  task.plan_end_time >0 and (task.end_time > task.plan_end_time)
         * 二.任务未完成  (task.task_status != final and task.end_time <=0)
         *  1. 计划的结束时间小于当前时间 task.episode_id =数字 and task.step_category_id in (环节) and plan.end_time < time()
         *  2.任务的计划结束时间小于当前时间 task.plan_end_time < time()
         */


        $overdueFinalFilter = [ //任务完成
            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => $finalStatusId,
            "task.end_time" => ["GT", 0],
            $finalFilter
        ];

        $overdueUndoneFilter = [  //任务未完成
            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => ["NEQ", $finalStatusId],
            $undoneFilter
        ];

        $overdueFilter = [
            //任务完成
            $overdueFinalFilter,
            //任务未完成
            $overdueUndoneFilter,
            "_logic" => "OR"
        ];

        // 异常情况 (有工单 ,且逾期) [时间范围 = 计划集 + 任务时间范围的]
        $abnormalFilter = [["task_work_order.id" => ["GT", 0]], [$overdueFilter], "_logic" => "OR"];

        return [
            'abnormal_filter' => $abnormalFilter,
            'overdue_final_filter' => $overdueFinalFilter,
            'overdue_undone_filter' => $overdueUndoneFilter,
        ];
    }

    /**
     * 获取人员任务统计
     * @param $filter
     * @param $fields
     * @param bool $joinEpisode
     * @param null $queryTaskWork
     * @param array $noDealStatus
     * @return array
     */
    public function getMemberTaskCount($filter, $fields, $joinEpisode = true, $queryTaskWork = null, $noDealStatus = [])
    {
        $countQuery = model(TaskModel::class);

        if ($joinEpisode) {
            $countQuery = $countQuery->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT");
        }

        $countQuery = $countQuery->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
            ->join("task_member on task_member.task_id = task.id");


        if (isset($queryTaskWork)) {
            if ($queryTaskWork == "all") {
                $countQuery = $countQuery->join("task_work_order on task_work_order.task_id = task.id", "LEFT");
            } else {
                $countQuery = $countQuery->join("task_work_order on task_work_order.task_id = task.id and task_work_order.status in ({$noDealStatus})", "LEFT");
            }
        }

        $count = $countQuery->where($filter)
            ->field($fields)
            ->group("task_member.user_id")
            ->select();

        return array_column($count, null, 'user_id');
    }

    /**
     * 处理统计
     * @param $taskFilter
     * @param $type
     * @param $statusCodeMap
     * @param $noDealStatus
     * @param $finalOverdueFilter
     * @param $undoneOverdueFilter
     * @param $unSolveFilter
     * @return array
     */
    public function dealTaskProgressInfoCount($taskFilter, $type, $statusCodeMap, $noDealStatus, $finalOverdueFilter, $undoneOverdueFilter, $unSolveFilter)
    {
        $finalStatusId = $statusCodeMap['final']['id'] ?? 0;
        $reviewingStatusId = $statusCodeMap['submitted']['id'] ?? 0;

        $res = [];
        switch ($type) {
            case 'plan_final':
            case 'plan_delivery':
                $taskCount = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task.id = task_member.task_id")
                    ->join("entity on task.entity_id = entity.id", 'LEFT')
                    ->join("module on entity.module_id = module.id", 'LEFT')
                    ->where($taskFilter)
                    ->count('distinct task.id');


                $finalTaskCountFilter = $taskFilter;
                $finalTaskCountFilter["json_unquote(json_extract(task.json, '$.task_status'))"] = $finalStatusId;

                $finalTaskCount = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task.id = task_member.task_id")
                    ->join("entity on task.entity_id = entity.id", 'LEFT')
                    ->join("module on entity.module_id = module.id", 'LEFT')
                    ->where($finalTaskCountFilter)
                    ->count('distinct task.id');

                $reviewingTaskCountFilter = $taskFilter;
                $reviewingTaskCountFilter["json_unquote(json_extract(task.json, '$.task_status'))"] = $reviewingStatusId;
                $reviewingTaskCount = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task.id = task_member.task_id")
                    ->join("entity on task.entity_id = entity.id", 'LEFT')
                    ->join("module on entity.module_id = module.id", 'LEFT')
                    ->where($reviewingTaskCountFilter)
                    ->count('distinct task.id');


                $undoneTaskCountFilter = $taskFilter;
                $undoneTaskCountFilter["json_unquote(json_extract(task.json, '$.task_status'))"] = ['NEQ', $finalStatusId];
                $undoneTaskCount = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task.id = task_member.task_id")
                    ->join("entity on task.entity_id = entity.id", 'LEFT')
                    ->join("module on entity.module_id = module.id", 'LEFT')
                    ->where($undoneTaskCountFilter)
                    ->count('distinct task.id');

                $res['total'] = $taskCount;
                $res['complete_count'] = $finalTaskCount;
                $res['reviewing_count'] = $reviewingTaskCount;
                $res['undone_count'] = $undoneTaskCount;
                break;
            case 'abnormal':
                $taskCount = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task.id = task_member.task_id")
                    ->join("entity on task.entity_id = entity.id", 'LEFT')
                    ->join("module on entity.module_id = module.id", 'LEFT')
                    ->join("task_work_order on task_work_order.task_id = task.id", "LEFT")
                    ->where($taskFilter)
                    ->count("distinct task.id");
                $res['total'] = $taskCount;

                //未解决异常
                $unSolveCount = model(TaskModel::class)
                    ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                    ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                    ->join("task_member on task.id = task_member.task_id")
                    ->join("entity on task.entity_id = entity.id", 'LEFT')
                    ->join("module on entity.module_id = module.id", 'LEFT')
                    ->join("task_work_order on task_work_order.task_id = task.id and task_work_order.status in ({$noDealStatus})", "LEFT")
                    ->where($unSolveFilter)
                    ->count("distinct task.id");
                $res['unsolved_count'] = $unSolveCount;
                break;
        }


        //异常的统计
        if ($type != 'abnormal') {
            $currentTime = time();
            $abnormalFilter = $taskFilter;
            switch ($type) {
                case 'plan_final':
                    //计划完成的异常计算 , 判定完成是是否超过
                    $abnormalFilter[] = [
                        "task_work_order.id" => ["GT", 0],
                        // 逾期完成
                        [
                            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => $finalStatusId,
                            'task.plan_end_time' => ["GT", 0], 'task.end_time' => ['GT', 0], "_string" => "task.end_time>task.plan_end_time"
                        ],
                        // 逾期未完成
                        [
                            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => ["NEQ", $finalStatusId],
                            "task.end_time" => 0, "task.plan_end_time" => ["LT", $currentTime]
                        ],
                        "_logic" => "OR"
                    ];
                case 'plan_delivery':
                    $abnormalFilterTmp = [
                        "task_work_order.id" => ["GT", 0]
                    ];
                    if (!empty($finalOverdueFilter)) {
                        $abnormalFilterTmp[] = [
                            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => $finalStatusId,
                            'task.plan_end_time' => ["GT", 0],
                            $finalOverdueFilter,
                        ];
                        $abnormalFilterTmp["_logic"] = "OR";
                    }

                    if (!empty($undoneOverdueFilter)) {
                        $abnormalFilterTmp[] = [
                            "JSON_UNQUOTE(JSON_EXTRACT(task.json,'$.task_status'))" => ["NEQ", $finalStatusId],
                            "task.end_time" => 0,
                            $undoneOverdueFilter
                        ];
                        $abnormalFilterTmp["_logic"] = "OR";
                    }

                    $abnormalFilter[] = $abnormalFilterTmp;
                    break;
            }

            //异常统计
            $abnormalCount = model(TaskModel::class)
                ->join("task_relation_tag r_episode on r_episode.task_id = task.id and r_episode.link_module_code = 'episode'", "LEFT")
                ->join("task_relation_tag r_step_category on r_step_category.task_id = task.id and r_step_category.link_module_code in ('step_category','show_step_category')", 'LEFT')
                ->join("task_member on task.id = task_member.task_id")
                ->join("entity on task.entity_id = entity.id", 'LEFT')
                ->join("module on entity.module_id = module.id", 'LEFT')
                ->join("task_work_order on task_work_order.task_id = task.id and task_work_order.status in ({$noDealStatus})", "LEFT")
                ->where($abnormalFilter)
                ->count("distinct task.id");
            $res['abnormal_count'] = $abnormalCount;
        }

        return $res;
    }
}
